import axios from 'axios';
import Vue from 'vue';

const pathMap = new Map([
  // ------------------------- 登陆 -------------------------
  // 发送验证码
  ['login_sent', '/captcha/sent'],
  // 验证码验证
  ['login_verify', '/captcha/verify?phone=131xxxx4970&captcha=xxxx'],
  // 检测手机号码是否已注册
  ['login_isRegistered', '/cellphone/existence/check'],
  // 注册(修改密码)
  ['login_register', '/register/cellphone'],
  // 初始化昵称
  ['login_initName', '/activate/init/profile'],
  // 通过手机号登陆
  ['login_cellphone', '/login/cellphone'],
  // 通过邮箱登陆
  ['login_email', '/login'],
  // 刷新登录状态
  ['login_refresh', '/login/refresh'],
  // 登录状态
  ['login_status', '/login/status'],
  // 退出登录
  ['login_logout', '/logout'],
  // ------------------------- 搜索 -------------------------
  // 热搜列表(简略)
  ['search_hot', '/search/hot'],
  // 热搜列表(详细)
  ['search_hot_detail', '/search/hot/detail'],
  // 搜索建议
  ['search_suggest', '/search/suggest'],
  // 搜索
  ['search', '/search'],
  // ------------------------- 音乐 -------------------------
  // 音乐是否可用 - 调用此接口,传入歌曲 id, 可获取音乐是否可用
  ['music_suggest', '/check/music'],
  // 获取音乐 url
  ['music_url', '/song/url'],
  // 获取歌词 - 传入音乐 id 可获得对应音乐的歌词 ( 不需要登录 )
  ['music_lyric', '/lyric'],
  // 获取歌手单曲 - 传入歌手id, 可获得歌手部分信息和热门歌曲
  ['music_singer', '/artists'],
  // 获取歌手描述 - 传入歌手id, 可获得歌手描述
  ['music_singer-describes', '/artist/desc'],
  // ------------------------- 用户 -------------------------
  // 获取用户信息 歌单|收藏|mv|dj 数量
  ['user_subcount', '/user/subcount'],
  // 获取用户详情
  ['user_detail', '/user/detail'],
  // 获取用户歌单
  ['user_playlist', '/user/playlist'],
  // 获取用户粉丝列表
  ['user_Fan-list', '/user/followeds?uid=445746067'],
  // 首页轮播图
  ['home_banner', '/banner?type=0'],
  // ------------------------- 推荐 -------------------------
  // 推荐歌单
  ['reco_playlist-min', '/personalized'],
  // 独家放送
  ['reco_privatecontent', '/personalized/privatecontent'],
  // 推荐 mv
  ['reco_mv', '/personalized/mv'],
  // 最新音乐
  ['reco_newMusic', '/personalized/newsong'],
  // 推荐电台
  ['reco_djprogram', '/personalized/djprogram'],
  // 主播电台页轮播图
  ['reco_djBanner', '/dj/banner'],
  // 所有榜单
  ['reco_toplist', '/toplist'],
  // 热门歌单分类
  ['reco_playlist-classify', '/playlist/hot'],
  // 歌单 ( 网友精选碟 )
  ['reco_playlist', '/top/playlist'],
  // 获取精品歌单
  ['reco_playlist-highquality', '/top/playlist/highquality'],
  // 歌手分类列表
  ['reco_artist', '/artist/list'],
  // 新歌速递 - type 全部:0 华语:7 欧美:96 日本:8 韩国:16
  ['reco_new-music', '/top/song'],
  // 新碟上架
  ['reco_new-album', '/top/album?offset=0&limit=30']
]);

export default class Req {
  static fake = false; // 启用假数据渲染

  static record = false; // 记录历史请求的轨迹

  static log = []; // 历史请求

  static get(key, params = {}, stringent) {
    const url = pathMap.get(key) || key;
    // eslint-disable-next-line no-param-reassign
    if (params === true) params = {};
    const oP = axios.get(url, { params });
    const is = params === true ? params : stringent;
    return this.processingError(this.intercept(oP, url), is);
  }

  static post(key, query = {}, stringent) {
    const url = pathMap.get(key) || key;
    // eslint-disable-next-line no-param-reassign
    if (query === true) query = {};
    const oP = axios.post(url, query);
    const is = query === true ? query : stringent;
    return this.processingError(this.intercept(oP, url), is);
  }

  static processingError(oP, stringent) {
    if (stringent !== true) return oP;
    return oP.then((data) => {
      if (data.code !== 200) {
        const msg = data.message || data.msg;
        if (msg) {
          Vue.prototype.$message({
            showClose: true,
            type: 'error',
            message: msg
          });
        }
        return Promise.reject(data);
      }
      return Promise.resolve(data);
    });
  }

  static intercept(oP, url) {
    return oP.then(({ data }) => {
      // 请求成功
      this.record && this.log.push({ url, status: 'resolved', result: data });
      return Promise.resolve(data);
    }).catch((error) => {
      // 请求失败时处理错误信息(提示)
      const { response } = error;
      let errMes = 'Request unsuccessful';
      const ignore = [301]; // 屏蔽部分状态码的提示。
      let state = null;
      if (!response) {
        errMes = error.message;
      } else {
        const { status, statusText, data } = response;
        state = status;
        errMes = `${status} - ${statusText}`;
        if (typeof data === 'object') {
          const msg = data.message || data.msg || '请求失败，后端响应异常'; // 兼容后端不统一的情况
          errMes = `${status} - ${msg}`;
        }
      }
      if (ignore.indexOf(state) === -1) {
        Vue.prototype.$message({
          showClose: true,
          type: 'error',
          message: errMes
        });
      }
      this.record && this.log.push({ url, status: 'rejected', result: errMes });
      return Promise.reject(error);
    });
  }
}
